<template>
  <div>
    <el-form :inline="true">
      <el-form-item>
        <el-input v-model="filterText" prefix-icon="el-icon-search" placeholder="输入查找的目录" clearable style="width: 85%;margin-right: 10px;" />
        <el-tooltip v-if="showAddBtn" content="点击可新建根目录, 子目录需要在树上新建" placement="top-start">
          <svg-icon icon-class="add-folder" class="clickable-icon" @click="addCatalog" />
        </el-tooltip>
      </el-form-item>
    </el-form>
    <el-tree
      ref="tree"
      class="filter-tree"
      element-loading-text="加载中"
      :data="catalogs"
      node-key="id"
      :props="defaultProps"
      :filter-node-method="filterNode"
      :expand-on-click-node="false"
      :default-expanded-keys="defaultExpandedKeys"
      highlight-current
      @node-click="handleNodeClick"
    >
      <span slot-scope="{ node, data }" class="custom-tree-node" style="display: flex; width: 180px" @mouseenter="mouseenter(data)" @mouseleave="mouseleave(data)">
        <span style="overflow: hidden; text-overflow:ellipsis; flex: 1">
          <i class="el-icon-folder" />&nbsp;&nbsp;{{ node.label }}
        </span>
        <span v-show="data.del" class="icon-group">
          <el-button type="text" icon="el-icon-folder-add" @click="addCatalog(node, data)" />
          <el-button type="text" icon="el-icon-edit" @click="editCatalog(node, data)" />
          <el-button type="text" icon="el-icon-delete" @click="deleteCatalog(node, data)" />
        </span>
      </span>
    </el-tree>

    <el-dialog :title="catalogDialogTitle" :visible.sync="catalogDialogShow" width="25%">
      <el-form ref="catalogForm" :model="catalogForm" :rules="catalogFormRules" label-width="55px">
        <el-form-item label="目录" prop="name">
          <el-input v-model="catalogForm.name" placeholder="目录" />
        </el-form-item>
        <el-form-item label="排序" prop="order">
          <el-input-number v-model="catalogForm.order" :min="1" :max="999" label="排序序号" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="catalogDialogShow=false">取 消</el-button>
        <el-button type="primary" @click="saveSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import api from '@/api/public/catalog'
const defaultForm = {
  id: '',
  name: '',
  order: 1,
  catalog_type: null,
  parent_id: null,
  relate_id: null
}
export default {
  name: 'CatalogTree',
  props: {
    showAddBtn: {
      type: Boolean,
      required: false,
      default() { return true }
    },
    catalogType: {
      type: Number,
      required: true
    },
    relatedId: {
      type: Number,
      required: false,
      default() { return }
    }
  },
  data() {
    return {
      filterText: '',
      catalogs: [],
      catalogForm: defaultForm,
      defaultExpandedKeys: [],
      catalogFormRules: {
        name: [
          { required: true, message: '目录名不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '最长50个字符', trigger: 'blur' }
        ]
      },
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      catalogDialogShow: false,
      catalogDialogTitle: '新增目录',
      submitType: 0 // 0:新增 1:编辑
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    relatedId(val) {
      this.getCatalogTree()
    }
  },
  created() {
    this.getCatalogTree()
  },
  methods: {
    filterNode(value, data) {
      if (!value) return true
      return data[this.defaultProps.label].indexOf(value) !== -1
    },
    mouseenter(data) {
      this.$set(data, 'del', true)
    },
    mouseleave(data) {
      this.$set(data, 'del', false)
    },
    getCatalogTree() {
      const params = {
        catalog_type: this.catalogType,
        related_id: this.relatedId
      }
      api.getCatalogTree(params).then(response => {
        this.catalogs = response.data
        this.$emit('throwCatalogList', response.data)
      })
    },
    addCatalog(node = null, data = null) {
      this.catalogDialogShow = true
      this.submitType = 0
      this.catalogDialogTitle = '新增目录'
      this.catalogForm = Object.assign({}, defaultForm)
      this.catalogForm.related_id = this.relatedId
      this.catalogForm.catalog_type = this.catalogType
      if (data) {
        this.catalogForm.parent_id = data.id
      }
    },
    editCatalog(node = null, data) {
      this.catalogDialogShow = true
      this.submitType = 1
      this.catalogDialogTitle = '修改目录'
      this.catalogForm = Object.assign({}, data)
    },
    async saveSubmit() {
      this.$refs.catalogForm.validate(async validate => {
        if (validate) {
          if (this.submitType === 0) {
            await api.createCatalog(this.catalogForm).then(response => {
              this.$message.success(response.message || '新增成功')
            })
          } else {
            await api.updateCatalog(this.catalogForm).then(response => {
              this.$message.success(response.message || '修改成功')
            })
          }
          this.catalogDialogShow = false
          await this.getCatalogTree()
        }
      })
    },
    async deleteCatalog(node = null, data) {
      this.$confirm('确定要删除吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        lockScroll: false,
        type: 'warning'
      }).then(async() => {
        const dataList = [data.id]
        await api.deleteCatalog(dataList).then(response => {
          this.$message.success(response.message || '删除成功')
          this.getCatalogTree()
        })
      })
    },
    handleNodeClick(data, node, component) {
      const dataAttr = this.findParentIds(this.catalogs, data.id)
      this.defaultExpandedKeys = dataAttr
      this.selectedNodeIds = []
      this.getNodeIds(node)
      this.$emit('changeCatalogId', this.selectedNodeIds)
    },
    findParentIds(dataSource, nodeId) {
      const parentIds = [] // 用于存储所有父节点ID的数组
      // 定义一个递归函数，用于遍历整棵树并查找子节点的所有父节点
      function traverse(node, nodeId) {
        if (node.id === nodeId) {
          // 如果当前节点的ID等于子节点的ID，则表示已经找到了子节点，可以开始向上查找父节点
          return true // 返回true表示已经找到了子节点
        }
        if (node.child) {
          // 如果当前节点有子节点，则继续遍历子节点
          for (const childNode of node.child) {
            if (traverse(childNode, nodeId)) {
              // 如果在子节点中找到了子节点的父节点，则将当前节点的ID添加到父节点ID数组中，并返回true表示已经找到了子节点
              parentIds.push(node.id)
              return true
            }
          }
        }
        return false // 如果当前节点不是子节点的父节点，则返回false
      }
      // 从根节点开始遍历整棵树，并调用递归函数查找子节点的所有父节点
      for (const node of dataSource) {
        if (traverse(node, nodeId)) {
          // 如果在当前节点的子树中找到了子节点的父节点，则直接退出循环
          break
        }
      }
      return parentIds.length ? [...parentIds, nodeId] : [nodeId] // 返回所有父节点ID和自身id
    },
    getNodeIds(node) {
      this.selectedNodeIds.push(node.data.id)
      if (node.childNodes && node.childNodes.length > 0) {
        node.childNodes.forEach(childNode => {
          this.getNodeIds(childNode)
        })
      }
    }
  }
}
</script>

  <style scoped>
   .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
  </style>
